package com.dbflow5.query;

import com.dbflow5.config.FlowLog;
import com.dbflow5.database.DatabaseStatement;
import com.dbflow5.database.DatabaseStatementWrapper;
import com.dbflow5.database.DatabaseWrapper;
import com.dbflow5.database.FlowCursor;
import com.dbflow5.sql.Query;
import com.dbflow5.structure.ChangeAction;

import java.util.List;

/**
 * Description: Provides a very basic query mechanism for strings. Allows you to easily perform custom SQL cursor string
 * code where this library does not provide. It only runs a
 * [SQLiteDatabase.rawQuery].
 */
public class StringQuery<T> extends BaseModelQueriable<T> implements Query, ModelQueriable<T> {
    private String[] args = null;
    private final String query;

    public StringQuery(Class<T> table, String query) {
        super(table);
        this.query = query;
    }

    @Override
    public String getQuery() {
        return query;
    }

    @Override// we don't explicitly know the change, but something changed.
    public ChangeAction primaryAction() {
        return ChangeAction.CHANGE;
    }

    @Override
    public FlowCursor cursor(DatabaseWrapper databaseWrapper) {
        return databaseWrapper.rawQuery(query, args);
    }

    @Override
    public List<T> queryList(DatabaseWrapper databaseWrapper) {
        FlowLog.log(FlowLog.Level.V, "Executing query: " + query);
        return listModelLoader().load(cursor(databaseWrapper), databaseWrapper);
    }

    @Override
    public T querySingle(DatabaseWrapper databaseWrapper) {
        FlowLog.log(FlowLog.Level.V, "Executing query: " + query);
        return singleModelLoader().load(cursor(databaseWrapper), databaseWrapper);
    }

    @Override
    public <QueryClass> List<QueryClass> queryCustomList(Class<QueryClass> queryModelClass, DatabaseWrapper databaseWrapper) {
        String query = getQuery();
        FlowLog.log(FlowLog.Level.V, "Executing query: " + query);
        return getListQueryModelLoader(queryModelClass).load(cursor(databaseWrapper), databaseWrapper);
    }

    @Override
    public <QueryClass> QueryClass queryCustomSingle(Class<QueryClass> queryModelClass, DatabaseWrapper databaseWrapper) {
        String query = getQuery();
        FlowLog.log(FlowLog.Level.V, "Executing query: " + query);
        return getSingleQueryModelLoader(queryModelClass).load(cursor(databaseWrapper), databaseWrapper);
    }

    @Override
    public DatabaseStatement compileStatement(DatabaseWrapper databaseWrapper) {
        String query = getQuery();
        FlowLog.log(FlowLog.Level.V, "Compiling Query Into Statement: query = "+query+" , args = "+args);
        return new DatabaseStatementWrapper<>(databaseWrapper.compileStatement(query, args), this);
    }

    @Override
    public Class<T> table() {
        return null;
    }

    /**
     * Set selection arguments to execute on this raw query.
     * @param args args
     * @return this
     */
    public StringQuery<T> setSelectionArgs(String[] args) {
        this.args = args;
        return this;
    }
}
